/*
 * Copyright (C) 2010-2011 Graz University of Technology, Austria. All Rights reserved. 
 *
 * Contact: Simone Kopeinik <simone.kopeinik@tugraz.at>
 * 	   Graz University of Technology, Knowledge Management Institute, Brückenkopfgasse 1/6, 8020 Graz 	
 * 	   <http://www.kmi.tugraz.at/>
 * 
 * This software is part of the TARGET platform developed by the
 * TARGET EC-funded project www.reachyourtarget.org
 *
 * This software is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * The GNU General Public License is available at <http://www.gnu.org/licenses/>.
 *
 */
package at.tugraz.kmi.css.cbkst2;

import com.google.inject.Inject;

/**
 * Prerequisite relations establish dependency relations among problems or
 * competences which are mandatory.
 * 
 * @author Georg Öttl <georg.oettl@gmail.com>
 */
public class PrerequesiteRelation implements Relation {

	private final CbKSTCompetence	ancestor;

	private final CbKSTCompetence	descendant;

	private final String			id;

	/**
	 * @param ancestor
	 *            The ancestor vertex
	 * @param descendant
	 *            The descendant Vertex
	 */
	@Inject
	public PrerequesiteRelation(CbKSTCompetence ancestor,
			CbKSTCompetence descendant) {
		this("Prerequesite", ancestor, descendant);
	}

	/**
	 * The default constructor.
	 * 
	 * @param id
	 *            The id of the relation
	 * @param ancestor
	 * @param descendant
	 */
	public PrerequesiteRelation(String id, CbKSTCompetence ancestor,
			CbKSTCompetence descendant) {
		if (id == null || ancestor == null || descendant == null) {
			throw new IllegalArgumentException("id can't be null");
		}
		this.ancestor = ancestor;
		this.descendant = descendant;
		this.id = id;
	}

	/**
	 * 
	 * Creates a new prerequisite relation.
	 * 
	 * @param id
	 *            U unique ID for this competence.
	 * 
	 * @param ancestor
	 *            The ancestor of this prerequisite relation.
	 * @param descendant
	 *            The descendant of this prerequisite relation.
	 * @return A new prerequisite relation.
	 */
	public static PrerequesiteRelation of(String id, CbKSTCompetence ancestor,
			CbKSTCompetence descendant) {
		return new PrerequesiteRelation(id, ancestor, descendant);
	}

	/**
	 * 
	 * @param ancestor
	 * @param descendant
	 * 
	 * @return A newly created prerequesite relation
	 */
	public static PrerequesiteRelation of(CbKSTCompetence ancestor,
			CbKSTCompetence descendant) {
		return new PrerequesiteRelation(ancestor, descendant);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getId() {
		return id;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public CbKSTCompetence getAncestor() {
		return ancestor;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public CbKSTCompetence getDescendant() {
		return descendant;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((ancestor == null) ? 0 : ancestor.hashCode());
		result = prime * result
				+ ((descendant == null) ? 0 : descendant.hashCode());
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		PrerequesiteRelation other = (PrerequesiteRelation) obj;
		if (ancestor == null) {
			if (other.ancestor != null) {
				return false;
			}
		} else if (!ancestor.equals(other.ancestor)) {
			return false;
		}
		if (descendant == null) {
			if (other.descendant != null) {
				return false;
			}
		} else if (!descendant.equals(other.descendant)) {
			return false;
		}
		if (id == null) {
			if (other.id != null) {
				return false;
			}
		} else if (!id.equals(other.id)) {
			return false;
		}
		return true;
	}

	@Override
	public String toString() {
		return ancestor.getId() + "->" + descendant.getId();
	}

}
